import re
from django.contrib.auth import authenticate
from django.core import exceptions
from django.core.cache import cache
from rest_framework.exceptions import ValidationError, APIException
from rest_framework import serializers

from .models import UserInfo
from rest_framework_jwt.settings import api_settings

jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER


class UserMulLoginSerializer(serializers.ModelSerializer):
    username = serializers.CharField()

    class Meta:
        model = UserInfo
        fields = ['username', 'password']

    def _get_user(self, attrs):
        username = attrs.get('username')
        password = attrs.get('password')
        if re.match(r'^1[3-9][0-9]{9}$', username):
            user = UserInfo.objects.filter(mobile=username).first()
        elif re.match(r'^.+@.+$', username):  # adsa@adsf  会有bug，用户名中如果有@，登录不了了
            user = UserInfo.objects.filter(email=username).first()
        else:
            user = UserInfo.objects.filter(username=username).first()
        if user and user.check_password(password):
            return user
        else:
            raise ValidationError('用户名或密码错误')

    def _get_token(self, user):
        try:
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)
            return token
        except Exception as e:
            raise ValidationError(str(e))

    def validate(self, attrs):
        user = self._get_user(attrs)
        token = self._get_token(user)
        self.context['token'] = token
        self.context['username'] = user.username
        self.context['icon'] = 'http://127.0.0.1:8000/media/' + str(user.icon)
        return attrs


class UserMobileLoginSerializer(serializers.ModelSerializer):
    code = serializers.CharField()
    mobile = serializers.CharField()

    class Meta:
        model = UserInfo
        fields = ['mobile', 'code']

    def _get_user(self, attrs):
        mobile = attrs.get('mobile')
        code = attrs.get('code')
        old_code = cache.get('sms_code_%s' % mobile)
        if code == old_code:
            user = UserInfo.objects.filter(mobile=mobile).first()
            return user
        raise APIException('验证码错误')

    def _get_token(self, user):
        try:
            payload = jwt_payload_handler(user)
            token = jwt_encode_handler(payload)
            return token
        except Exception as e:
            raise ValidationError(str(e))

    def validate(self, attrs):
        user = self._get_user(attrs)
        token = self._get_token(user)
        self.context['token'] = token
        self.context['username'] = user.username
        self.context['icon'] = 'http://127.0.0.1:8000/media/' + str(user.icon)
        return attrs


class UserMobileRegisterSerializer(serializers.ModelSerializer):
    code = serializers.CharField(write_only=True)

    class Meta:
        model = UserInfo
        fields = ['mobile', 'password', 'code']
        extra_kwargs = {
            'password': {
                'min_length': 8,
                'max_length': 16,
                'write_only': True,
            }
        }

    def validate_mobile(self, value):
        if not re.match(r'^1[3-9][0-9]{9}$', value):
            raise exceptions.ValidationError('mobile field error')
        return value

    def validate(self, attrs):
        mobile = attrs.get('mobile')
        code = attrs.get('code')
        old_code = cache.get('sms_code_%s' % mobile)
        if code != old_code:
            raise APIException(detail='验证码错误')
        if UserInfo.objects.filter(mobile=mobile).first():
            raise APIException(detail='该手机号已经被注册过')
        attrs.pop('code')
        attrs['username'] = mobile
        return attrs

    def create(self, validated_data):
        return UserInfo.objects.create_user(**validated_data)

